import { formatNum } from '../util'

const CRC8 = 0xd5
const CRC8_CCITT = 0x07
const CRC8_DALLAS_MAXIM = 0x31
const CRC8_SAE_J1850 = 0x1D
const CRC_8_WCDMA = 0x9b

class Crc {
  initial_value
  table
  constructor (polynomial, initial_value) {
    if (!polynomial) polynomial = CRC8_CCITT
    this.table = generateTable(polynomial)
    this.initial_value = initial_value
  }
  // 接受数据验证crc是否正确
  checkCrc (data) {
    let crc = data.substr(data.length - 2, 2)
    return crc === this.calculateCrc(data.substr(0, data.length - 2))
  }
  // 发送数据计算crc
  calculateCrc (data) {
    let ArrayData = []
    for (let i = 0; i < data.length; i+=2) {
      ArrayData.push(parseInt(data.substring(i, i + 2), 16))
    }
    // 把十进制的ArrayData转化crc
    const checksum = this.checksum(ArrayData)
    let value = formatNum(parseInt(checksum).toString(16))
    return value
  }
  // Returns the 8-bit checksum given an array of byte-sized numbers
  checksum (byte_array) {
    var c = this.initial_value
    for (var i = 0; i < byte_array.length; i++)
      c = this.table[(c ^ byte_array[i]) % 256]
    return c
  }
}

function generateTable (polynomial) {
  let csTable = [] // 256 max len byte array
  for (let i = 0; i < 256; ++i) {
    let curr = i
    for (let j = 0; j < 8; ++j) {
      if ((curr & 0x80) !== 0) {
        curr = ((curr << 1) ^ polynomial) % 256
      } else {
        curr = (curr << 1) % 256
      }
    }
    csTable[i] = curr
  }
  return csTable
}

export default new Crc()
